package com.tckdq.tcc.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tckdq.tcc.constants.RedisConstant;
import com.tckdq.tcc.domain.*;
import com.tckdq.tcc.dto.SMSVerifiy2RedisDto;
import com.tckdq.tcc.exception.GlobalException;
import com.tckdq.tcc.feign.Feign;
import com.tckdq.tcc.mapper.UserMapper;
import com.tckdq.tcc.result.JsonResult;
import com.tckdq.tcc.service.*;
import com.tckdq.tcc.utils.BitStatesUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author whale
 * @since 2022-08-12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IUserAccountService userAccountService;

    @Autowired
    private IUserBaseInfoService userBaseInfoService;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private Feign feign;
    @Autowired
    private IInvitationService invitationService;
   /* @Autowired
    private ICourseService courseService;*/
    @Override
    public User selectByphone(String phone) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("phone",phone);
        return selectOne(wrapper);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(UserDto userDto) {
        check(userDto);

        VerificationCode(userDto);

        Long loginId =savelonin(userDto.getMobile(), userDto.getPassword());

        User user = saveUser(loginId, userDto);
        Long userId = user.getId();

        saveUserAccount(userId);

        saveUserBaseInfo(userId,userDto);

        //删除redis和数据库中的邀请码
        if (!StringUtils.isEmpty(redisTemplate.opsForValue().get(RedisConstant.INVITATION_CODE+1L))){
            redisTemplate.delete(RedisConstant.INVITATION_CODE+1L);
            invitationService.deleteByCode(userDto.getInvitationCode());
        }
        /*
* 1.参数校验
* 2.条件判断
* 2.1手机验证码校验
* 2.2判断手机号是否注册过
* 3.保存login
* 4.保存user
* userAccount
* userBaseinfo
* */
    }
    //保存login
    public Long savelonin(String password,String username){
        Login login = new Login();
        login.setPassword(password);
        login.setUsername(username);

        long typeSys = Login.TYPE_SYS;
        String toString = Long.valueOf(typeSys).toString();
        String format = String.format(toString);
        Integer type = Integer.valueOf(format);
        login.setType(type);

        JsonResult jsonResult = feign.saveRegister(login);
        if(!jsonResult.isSuccess())throw new GlobalException("保存Login失败","");
        System.out.println(jsonResult);
        Long loginId = Long.valueOf(jsonResult.getData().toString());
        return loginId;
    }
    public void check(UserDto userDto){
        String phoneCode = userDto.getSmsCode();
        String mobile = userDto.getMobile();
        String password = userDto.getPassword();
        Integer reChannel = userDto.getReChannel();

        User user = selectByphone(mobile);
        if (user!=null){
            throw new GlobalException("该手机号被注册","不要重复注册");
        }
    }

    public void VerificationCode(UserDto userDto){
        String mobile = userDto.getMobile();
        String smsCode = userDto.getSmsCode();
        //1.从redis获取验证码,并判断
        SMSVerifiy2RedisDto redisDto = (SMSVerifiy2RedisDto)redisTemplate.opsForValue().get("register:" + mobile);
        //验证码设置为null
        String smscode =null;
        //2.判断
        if(redisDto==null){
            //若redis没有验证码,则第一次获取验证码,或者验证码过期,就重新创建验证码
            throw new GlobalException("验证码为空",null);
        }else {
            if (!smsCode.equals(redisDto.getCode())){
                throw new GlobalException("输入的验证码不正确",null);
            }

        }

        //3手机验证码保存redis
        SMSVerifiy2RedisDto redisDtoSet = new SMSVerifiy2RedisDto();
        Date date = new Date();
        long time = date.getTime();
        redisDtoSet.setTime(time);
        redisDtoSet.setCode(smscode);
        redisTemplate.opsForValue().set("register:" + mobile,redisDtoSet,3, TimeUnit.MINUTES);
    }

    public User saveUser(Long log_id,UserDto userDto){
        User user = new User();
        user.setCreateTime(new Date().getTime());
        user.setLoginId(log_id);
        user.setPhone(userDto.getMobile());
        user.setSecLevel(0);

        long state = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);

        long state1 = BitStatesUtils.addState(state, BitStatesUtils.OP_AUTHED_PHONE);

        user.setBitState(state1);

        String invitationCode = userDto.getInvitationCode();
        Invitation invitation = invitationService.selByCode(invitationCode);
        Long userId = invitation.getUserId();
        user.setInviter(userId);
        boolean insert = insert(user);
        return user;
    }
    public void saveUserAccount(Long userId){
        UserAccount userAccount = new UserAccount();
        userAccount.setCreateTime(new Date().getTime());
        userAccount.setFrozenAmount(new BigDecimal("0"));
        userAccount.setUsableAmount(new BigDecimal("0"));
        userAccount.setId(userId);
        userAccountService.insert(userAccount);
    }

    public void saveUserBaseInfo(Long userId,UserDto userDto){
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setCreateTime(new Date().getTime());
        userBaseInfo.setId(userId);
        userBaseInfo.setRegChannel(userDto.getReChannel());
        userBaseInfo.setLevel(0);
        userBaseInfoService.insert(userBaseInfo);
    }
}
